/**
 * 
 */
package br.edu.ufcg.embedded.mysocial;

import java.sql.Timestamp;
import java.util.Hashtable;
import java.util.LinkedHashSet;
import java.util.List;

import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.traverse.BreadthFirstIterator;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;

import br.edu.ufcg.embedded.util.Compressor;
import br.edu.ufcg.embedded.util.MultiFileGenerator;
import br.embedded.socialapp.business.Usuario;

/**
 * @author daniel
 *
 */
public class GraphCache3 extends Thread
{
	private List<Usuario> list;
	private int maxLevels;
	private MultiFileGenerator multiFileGenerator;
	private Compressor compressor;
	
	public GraphCache3(int maxLevels, List<Usuario> list)
	{
		this.list = list;
		this.maxLevels = maxLevels;
		
		this.compressor = new Compressor();
	}
	
	/**
	 * @param fileManager the fileManager to set
	 */
	public void setMultiFileGenerator(MultiFileGenerator multiFileGenerator) {
		this.multiFileGenerator = multiFileGenerator;
	}
	
	private void cacheFriendshipLevels()
	{
		for (int i = 0; i < list.size(); i++)
		{		
			Hashtable<Integer, LinkedHashSet<String>> hashtable = new Hashtable<Integer, LinkedHashSet<String>>();
			
			BreadthFirstIterator<Usuario, DefaultEdge> alg = 
				new BreadthFirstIterator<Usuario, DefaultEdge>(GraphCacheManager.getGraph(), list.get(i), maxLevels);
			alg.next();

			while(alg.hasNext())
			{
				Usuario n = alg.next();
				String login = n.getLogin();

				int level = alg.getDistanceFromStartVertex(n);
				
				if (!hashtable.containsKey(level))
					hashtable.put(level, new LinkedHashSet<String>());
				
				if (!hashtable.get(level).contains(login))
					hashtable.get(level).add(login);
			}
			//System.out.println(hashtable.get(hashtable.size()).size());
			write(list.get(i).getLogin(), hashtable);
			hashtable = null;
			
			//if (i % 100 == 0)
			//	System.out.println(this.getName() + " --> " + i);
		}
		multiFileGenerator.close();
		
		System.out.println(this.getName() + " has finished.");
	}

	@Override
	public void run() {
		this.cacheFriendshipLevels();
	}
		
	private void write(String login, Hashtable<Integer, LinkedHashSet<String>> hashtable)
	{
		//System.out.println(hashtable.size());
		XStream xstream = new XStream(new JettisonMappedXmlDriver());
		byte[] compressedData = compressor.compress(xstream.toXML(hashtable));
		multiFileGenerator.write(login + ";" + compressedData + ";" + new Timestamp(System.currentTimeMillis()) + ";" + compressedData.length);
		
		hashtable = null;
		login = null;
		compressedData = null;
	}
}
